package com.koron.ticket.work.common.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Opt;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.business.workflow.bean.properties.WorkflowProperties;
import com.koron.common.core.business.workflow.templates.WorkFlowHandler;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.ticket.enums.OperationTypeEnum;
import com.koron.ticket.operation.bean.OperationTicketBean;
import com.koron.ticket.operation.mapper.OperationWorkMapper;
import com.koron.ticket.utils.StringUtils;
import com.koron.ticket.work.common.bean.FifteenTables;
import com.koron.ticket.work.common.bean.Print;
import com.koron.ticket.work.common.bean.SixteenTables;
import com.koron.ticket.work.enums.TicketStatus;
import com.koron.ticket.work.workPermit.bean.WorkPermit;
import com.koron.ticket.work.workPermit.bean.WorkPermitQuery;
import com.koron.ticket.work.workPermit.service.WorkPermitService;
import com.koron.ticket.work.workend.service.WorkEndService;
import com.koron.ticket.work.workflow.bean.WorkFlow;
import com.koron.ticket.work.workflow.bean.WorkFlowQuery;
import com.koron.ticket.work.workflow.service.WorkFlowService;
import com.koron.ticket.work.workinfo.bean.WorkInfo;
import com.koron.ticket.work.workinfo.bean.WorkInfoQuery;
import com.koron.ticket.work.workinfo.service.WorkInfoService;
import com.koron.ticket.work.workline.bean.WorkLine;
import com.koron.ticket.work.workline.bean.WorkLineQuery;
import com.koron.ticket.work.workline.service.WorkLineService;
import com.koron.ticket.work.worklocation.bean.WorkLocationBean;
import com.koron.ticket.work.worklocation.service.WorkLocationService;
import com.koron.ticket.work.workmember.bean.WorkMember;
import com.koron.ticket.work.workmember.bean.WorkMemberQuery;
import com.koron.ticket.work.workmember.service.WorkMemberService;
import com.koron.ticket.work.workteam.bean.WorkTeam;
import com.koron.ticket.work.workteam.bean.WorkTeamQuery;
import com.koron.ticket.work.workteam.service.WorkTeamService;
import com.koron.ticket.work.workticket.bean.WorkTicket;
import com.koron.ticket.work.workticket.bean.WorkTicketQuery;
import com.koron.ticket.work.workticket.service.WorkTicketService;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SixteenTablesService {

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    private static Date currentTime = new Date();

    @Autowired
    private FifteenTablesService fifteenTablesService;

    @Autowired
    private WorkLineService workLineService;

    @Autowired
    private WorkFlowHandler workFlowHandler;

    @Autowired
    private WorkFlowService workFlowService;

    @Autowired
    private WorkTicketService workTicketService;

    @Autowired
    private WorkTeamService workTeamService;

    @Autowired
    private WorkInfoService workInfoService;

    @Autowired
    private WorkMemberService workMemberService;

    @Autowired
    private WorkLocationService worklocationservice;

    @Autowired
    private WorkPermitService workPermitService;

    @Autowired
    private WorkEndService workEndService;

    public String writeSave(SessionFactory factory, SixteenTables sixteenTables) {
        WorkTicket workTicket = sixteenTables.getWorkTicket();
        String workTicketId = workTicket.getId();

        // 1. 如果id为空，说明是新增
        if (StringUtils.isEmpty(workTicketId)) {
            // 1.1 先设置工作票的填写状态
            workTicket.setStatus(1);
            // 1.2 将预览标志设置为预览
            workTicket.setPreviewFlag(0);
            workTicketId = this.insert(factory, sixteenTables);
        } // 2. 如果id不为空，说明数据已存在，对现有的数据进行更新
        else {
            workTicketService.checkTimeOut(factory, sixteenTables.getWorkTicket().getId(), sixteenTables.getWorkTicket().getUpdateTime());//检查信息是否过期
            this.update(factory, sixteenTables);
        }
        return workTicketId;
    }

    @Transactional(rollbackFor = Exception.class)
    public String insert(SessionFactory factory, SixteenTables sixteenTables) {
        FifteenTables fifteenTables = new FifteenTables();
        fifteenTables.setWorkTicket(sixteenTables.getWorkTicket());
        fifteenTables.setWorkInfo(sixteenTables.getWorkInfo());
        fifteenTables.setWorkTeamList(sixteenTables.getWorkTeamList());
        fifteenTables.setWorkMemberList(sixteenTables.getWorkMemberList());
        fifteenTables.setSecurityArrangementList(sixteenTables.getSecurityArrangementList());
        String workTicketId = fifteenTablesService.insert(factory,fifteenTables);

        List<WorkLine> workLineList = sixteenTables.getWorkLineList();
        if (StringUtils.isNotEmpty(workLineList)) {
            workLineList.stream().forEach(w->{
                w.setWorkTicketId(workTicketId);
                w.setCreateTime(currentTime);
            });
            workLineService.batchInsert(factory, workLineList);
//            for (WorkLine workLine : workLineList) {
//                workLine.setWorkTicketId(workTicketId);
//                workLine.setCreateTime(currentTime);
//                workLineService.insert(factory, workLine);
//            }
        }

        return workTicketId;
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(SessionFactory factory, SixteenTables sixteenTables) {
        FifteenTables fifteenTables = new FifteenTables();
        fifteenTables.setWorkTicket(sixteenTables.getWorkTicket());
        fifteenTables.setWorkInfo(sixteenTables.getWorkInfo());
        fifteenTables.setWorkTeamList(sixteenTables.getWorkTeamList());
        fifteenTables.setWorkMemberList(sixteenTables.getWorkMemberList());
        fifteenTables.setSecurityArrangementList(sixteenTables.getSecurityArrangementList());
        fifteenTablesService.update(factory,fifteenTables);

        String workTicketId = sixteenTables.getWorkTicket().getId();
        List<WorkLine> workLineList = sixteenTables.getWorkLineList();
        workLineService.deleteByWorkTicketId(factory,workTicketId);
        if (StringUtils.isNotEmpty(workLineList)) {
            workLineList.stream().forEach(w->{
                w.setCreateTime(currentTime);
            });
            workLineService.batchInsert(factory, workLineList);
//            for (WorkLine workLine : workLineList) {
//                workLine.setCreateTime(currentTime);
//                workLineService.insert(factory, workLine);
//            }
        }
    }

    public String  writeSubmitByWorkFlowType(SessionFactory factory, SixteenTables sixteenTables, String workFlowType) {
        WorkTicket workTicket = sixteenTables.getWorkTicket();
        String workTicketId = workTicket.getId();
        String code = workTicket.getCode();
        String account = getCurrUser().getAccount();
        String name = getCurrUser().getName();
        Date currentTime = new Date();
        Map<String, String> form = new HashMap<>();
        form.put("user", account);

        // 1. 保存当前的数据
        // 1.1 因为是提交，所以装态要变成待签发
        workTicket.setStatus(TicketStatus.SIGN.getStatus());
        if (StringUtils.isEmpty(workTicketId)) {
            // 1.2 id为空，数据是新增的，workTicketId在新增的时候获取
            workTicketId = this.insert(factory, sixteenTables);
        } else {
            this.update(factory, sixteenTables);
        }
        // 2. 进入工作流
        WorkflowProperties wfp = WorkflowProperties.init(workFlowType);
        workFlowHandler.start(wfp, workTicketId, code, workTicket.getTitle(), form);
        // 3. 记录操作人
        WorkFlow workFlow = new WorkFlow();
        workFlow.setWorkTicketId(workTicketId);
        workFlow.setType("填写人");
        workFlow.setAccount(account);
        workFlow.setName(name);
        workFlow.setOperationTime(currentTime);
        workFlow.setDeleteFlag(0);
        workFlowService.insert(factory, workFlow, TicketStatus.WRITE.getStatus());
        // 4. 保存签名相关数据
        List<WorkFlow> workFlowList = sixteenTables.getWorkFlowList();
        if (workFlowList != null && workFlowList.size() > 0) {
            for (WorkFlow signWorkInfo : workFlowList) {
                signWorkInfo.setWorkTicketId(workTicketId);
                workFlowService.save(factory, signWorkInfo);
            }
        }

        return workTicketId;
    }

    public SixteenTables addByType(String type) {
        SixteenTables sixteenTables = new SixteenTables();

        // 1. 设置工作票类型
        WorkTicket workTicket = new WorkTicket();
        workTicket.setType(type);
        sixteenTables.setWorkTicket(workTicket);
        // 2. 设置当前用户信息
        sixteenTables.setCreateByName(getCurrUser().getName());
        sixteenTables.setCreateTime(currentTime);

        return sixteenTables;
    }

    public SixteenTables getById(SessionFactory factory, String id) {
        SixteenTables sixteenTables = new SixteenTables();

        FifteenTables fifteenTables = fifteenTablesService.getById(factory, id);
        sixteenTables.setWorkTicket(fifteenTables.getWorkTicket());
        sixteenTables.setWorkInfo(fifteenTables.getWorkInfo());
        sixteenTables.setWorkTeamList(fifteenTables.getWorkTeamList());
        sixteenTables.setWorkMemberList(fifteenTables.getWorkMemberList());
        sixteenTables.setSecurityArrangementList(fifteenTables.getSecurityArrangementList());
        sixteenTables.setWorkFlowList(fifteenTables.getWorkFlowList());
        sixteenTables.setWorkPermit(fifteenTables.getWorkPermit());
        sixteenTables.setWorkEndList(fifteenTables.getWorkEndList());
        sixteenTables.setTicketChange(fifteenTables.getTicketChange());

        WorkLineQuery workLineQuery = new WorkLineQuery();
        workLineQuery.setWorkTicketId(id);
        List<WorkLine> workLineList = workLineService.getList(factory,workLineQuery);
        sixteenTables.setWorkLineList(workLineList);

        OperationWorkMapper mapper = factory.getMapper(OperationWorkMapper.class);
        // 关联的工作票
        List<OperationTicketBean> operlist = mapper.queryByWorkId(id);
        if (CollUtil.isNotEmpty(operlist)) {
            List<String> aps = operlist.stream().filter(op -> op.getType().equals(OperationTypeEnum.TYPE_A.getValue())).map(OperationTicketBean::getCode).collect(Collectors.toList());
            List<String> bps = operlist.stream().filter(op -> op.getType().equals(OperationTypeEnum.TYPE_B.getValue())).map(OperationTicketBean::getCode).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(aps)) {
                sixteenTables.setOperationA(CollUtil.join(aps, ","));
            }
            if (CollUtil.isNotEmpty(bps)) {
                sixteenTables.setOperationB(CollUtil.join(bps, ","));
            }
        }

        return sixteenTables;
    }

    public List<Print> getPrintData(SessionFactory factory, String id) {
        List<Print> result = new ArrayList<>();
        Print print = new Print();

        WorkTicketQuery workTicketQuery = new WorkTicketQuery();
        workTicketQuery.setId(id);
        WorkTicket workTicket = workTicketService.getSingle(factory, workTicketQuery);
        Integer status = workTicket.getStatus();
        String ticketType = workTicket.getType();

        WorkTeamQuery workTeamQuery = new WorkTeamQuery();
        workTeamQuery.setWorkTicketId(id);
        List<WorkTeam> workTeamList = workTeamService.getList(factory, workTeamQuery);
        String workTeamListString = "";
        if (workTeamList.size() > 0) {
            workTeamListString = workTeamList.stream().map(WorkTeam::getWorkTeamName).collect(Collectors.joining(","));
        }

        WorkMemberQuery workMemberQuery = new WorkMemberQuery();
        workMemberQuery.setWorkTicketId(id);
        List<WorkMember> workMemberList = workMemberService.getList(factory, workMemberQuery);
        String workMemberListString = "";
        if (workMemberList.size() > 0) {
            workMemberListString = workMemberList.stream().map(WorkMember::getMemberName).collect(Collectors.joining(","));
        }

        WorkInfoQuery workInfoQuery = new WorkInfoQuery();
        workInfoQuery.setWorkTicketId(id);
        WorkInfo workInfo = workInfoService.getSingle(factory,workInfoQuery);

        WorkFlowQuery workFlowQuery = new WorkFlowQuery();
        workFlowQuery.setWorkTicketId(id);
        List<WorkFlow> workFlowList = workFlowService.getList(factory, workFlowQuery);

        WorkPermitQuery workPermitQuery = new WorkPermitQuery();
        workPermitQuery.setWorkTicketId(id);
        WorkPermit workPermit = workPermitService.getSingle(factory, workPermitQuery);

        // 1. 单位（部门）名称
        print.setConstruction(workInfo.getConstruction());
        // 2. 编号
        print.setCode(workTicket.getCode());
        // 3. 班组名称
        print.setWorkTeamNameListString(workTeamListString);
        // 4. 工作负责人
        print.setDirectorName(workTicket.getDirectorName());
        // 5. 电话
        print.setPhone(workInfo.getPhone());
        // 6. 工作班组人员
        print.setMemberNameListString(workMemberListString);
        // 7. 人数
        print.setNumber(workTicket.getNumber());
        // 8. 停电线路名称
        print.setEquipmentName(workInfo.getEquipmentName());
        // 9. 工作地点
        List<WorkLocationBean> worklocationlist = worklocationservice.getList(factory, id);
        String worklocationlistStr = "";
        if (worklocationlist.size() > 0) {
            worklocationlistStr = worklocationlist.stream().map(WorkLocationBean::getLocationName).collect(Collectors.joining(","));
        }
        print.setLocationName(worklocationlistStr);
        // 10. 工作内容
        print.setContent(workTicket.getContent());
        // 11. 保留的带电设备
        print.setEquipmentCharged(workInfo.getEquipmentCharged());
        // 12. 计划开始时间
        if (workTicket.getEstimatedStartTime() != null) {
            // 兼容计划开始时间为空的情况
            print.setEstimatedStartTime(DateUtil.format(workTicket.getEstimatedStartTime(), "yyyy年MM月dd日 HH时mm分"));
        }
        // 13. 计划结束时间
        if (workTicket.getEstimatedEndTime() != null) {
            // 兼容计划结束时间为空的情况
            print.setEstimatedEndTime(DateUtil.format(workTicket.getEstimatedEndTime(), "yyyy年MM月dd日 HH时mm分"));
        }
        // 14. 签发人
        if (status >= TicketStatus.SIGN.getStatus()) {
            // 14.1 先将所有的签发状态的数据聚合到一起
            List<WorkFlow> signList = workFlowList.stream().filter(workFlow ->
                    TicketStatus.SIGN.getStatus().equals(workFlow.getStatus())).collect(Collectors.toList());
            // 14.2 然后将所有数据中的名称拼接到一起
            String signNameListString = signList.stream().map(WorkFlow::getName).collect(Collectors.joining(","));
            print.setSignNameListString(signNameListString);
        }
        // 15. 工作票待接收
        if (status >= TicketStatus.ACCEPT.getStatus()) {
            for (WorkFlow workFLow:workFlowList) {
                if (workFLow.getStatus().equals(TicketStatus.ACCEPT.getStatus())) {
                    // 15.1 接收时间
                    Opt<String> optdate = Opt.of(DateUtil.format(workFLow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                    print.setAcceptTime(optdate.orElse(""));
                    // 15.2 接收人名称
                    print.setDutyPersonNameForAccept(workFLow.getName());
                    break;
                }
            }
        }
        // 16. 工作待许可
        if (status >= TicketStatus.PERMIT.getStatus()) {
            // 16.1 许可命令方式
            print.setPermitType(workPermit.getPermitType());
            for (WorkFlow workFlow:workFlowList) {
                if (workFlow.getStatus().equals(TicketStatus.PERMIT.getStatus()) && workFlow.getDeleteFlag().equals(0)) {
                    String type = workFlow.getType();
                    // 16.2 工作许可人
                    if (type.equals("工作许可人")) {
                        print.setPermitName(workFlow.getName());
                    } // 16.3 工作负责人
                    else if (type.equals("工作负责人")) {
                        print.setDirectorNameForPermit(workFlow.getName());
                    }
                }
            }
            // 16.4 许可工作时间 兼容待许可无数据
            print.setWorkTime(Opt.of(DateUtil.format(workPermit.getWorkTime(), "yyyy年MM月dd日 HH时mm分")).orElse(""));
        }
        // 17.
        return null;
    }

    public void deleteById(SessionFactory factory, String id) {
        // 当id不为空的时候，才有数据删除
        if (!StringUtils.isEmpty(id)) {
            // 1. 删除十五张表中的数据
            fifteenTablesService.deleteById(factory,id);
            // 2. 删除线路表中的数据
            workLineService.deleteByWorkTicketId(factory,id);
//            // 1. 主票信息删除
//            workTicketService.deleteById(factory, id);
//            // 2. 工作票详情删除
//            workInfoService.deleteByWorkTicketId(factory, id);
//            // 3. 工作班组删除
//            workTeamService.deleteByWorkTicketId(factory, id);
//            // 4. 工作班组成员删除
//            workMemberService.deleteByWorkTicketId(factory, id);
//            // 5. 许可信息删除
//            workPermitService.deleteByWorkTicketId(factory, id);
//            // 6. 终结信息删除
//            workEndService.deleteByWorkTicketId(factory, id);
//            // 7. 签名信息删除
//            workFlowService.deleteByWorkTicketId(factory, id);
//            // 8. 工作流删除
//            String workflow = workFlowHandler.queryView(id);
//            if (!StringUtils.isEmpty(workflow)) {
//                workFlowHandler.end(id);
//            }
        }
    }
}
